package com.yowasa.xiuxian.engine.battle.strategy;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yowasa.xiuxian.annoations.BS;
import com.yowasa.xiuxian.annoations.Buff;
import com.yowasa.xiuxian.entity.bo.battle.BattleContent;
import com.yowasa.xiuxian.entity.bo.battle.UserBattleContent;
import com.yowasa.xiuxian.engine.battle.buff.BuffInterface;
import com.yowasa.xiuxian.entity.enums.InherentTiming;
import com.yowasa.xiuxian.util.OrderUtil;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class BattleStrategyEngine implements InitializingBean {
    @Autowired
    private List<BattleStrategy> strategyList;

    @Autowired
    private List<BuffInterface> buffList;

    /**
     * 兜底攻击
     */
    @Autowired
    @Qualifier("baseBattleStrategy")
    private BaseBattleStrategy defaultBattleStrategy;

    /**
     * 兜底防御
     */
    @Autowired
    @Qualifier("baseDefendStrategy")
    private BaseDefendStrategy baseDefendStrategy;

    public static Map<String, BattleStrategy> strategyMap;

    public static Map<String, BuffInterface> buffMap;


    /**
     * 匹配进攻策略
     *
     * @param user
     * @param content
     * @return
     */
    public AttackStrategy matchAttackStrategy(UserBattleContent user, BattleContent content) {
        Set<String> battleStrategyList = user.getBattleStrategyList();
        if (CollectionUtils.isNotEmpty(battleStrategyList)) {
            List<BattleStrategy> bsList = battleStrategyList.stream().map(e -> strategyMap.get(e)).collect(Collectors.toList());
            OrderUtil.sortByOrder(bsList);
            for (BattleStrategy battleStrategy : bsList) {
                if (battleStrategy == null) {
                    continue;
                }
                if (!(battleStrategy instanceof AttackStrategy)) {
                    continue;
                }
                AttackStrategy attackStrategy = (AttackStrategy) battleStrategy;
                boolean check = attackStrategy.check(user, content);
                if (check) {
                    return attackStrategy;
                }
            }
        }
        return defaultBattleStrategy;
    }

    /**
     * 匹配防御策略
     *
     * @param user
     * @param content
     * @return
     */
    public List<DefendStrategy> matchDefendStrategy(UserBattleContent user, BattleStrategy bs, BattleContent content) {
        Set<String> battleStrategyList = user.getBattleStrategyList();
        List<DefendStrategy> result = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(battleStrategyList)) {
            for (String s : battleStrategyList) {
                BattleStrategy battleStrategy = strategyMap.get(s);
                if (battleStrategy == null) {
                    continue;
                }
                if (!(battleStrategy instanceof DefendStrategy)) {
                    continue;
                }
                DefendStrategy defendStrategy = (DefendStrategy) battleStrategy;
                boolean check = defendStrategy.check(user, bs, content);
                if (check) {
                    result.add(defendStrategy);
                }
            }
        }
        result.add(baseDefendStrategy);
        OrderUtil.sortByOrder(result);
        return result;
    }




    /**
     * 匹配永续策略
     *
     * @param user
     * @param content
     * @param timing
     * @return
     */
    public List<InherentStrategy> matchInherentStrategy(UserBattleContent user, BattleContent content, InherentTiming timing) {
        List<InherentStrategy> result = Lists.newArrayList();
        Set<String> battleStrategyList = user.getBattleStrategyList();
        if (CollectionUtils.isNotEmpty(battleStrategyList)) {
            for (String s : battleStrategyList) {
                BattleStrategy battleStrategy = strategyMap.get(s);
                if (battleStrategy == null) {
                    continue;
                }
                if (!(battleStrategy instanceof InherentStrategy)) {
                    continue;
                }
                InherentStrategy inherentStrategy = (InherentStrategy) battleStrategy;

                if (inherentStrategy.getTiming().contains(timing)) {
                    if (inherentStrategy.check(user, content)) {
                        result.add(inherentStrategy);
                    }
                }
            }
        }
        OrderUtil.sortByOrder(result);
        return result;
    }

    @Override
    public void afterPropertiesSet() {
        strategyMap = Maps.newHashMap();
        strategyList.stream().forEach(e -> {
            BS annotation = e.getClass().getAnnotation(BS.class);
            if (annotation != null) {
                String name = annotation.name();
                strategyMap.put(name, e);
            }
        });

        buffMap = Maps.newHashMap();
        buffList.stream().forEach(e -> {
            Buff annotation = e.getClass().getAnnotation(Buff.class);
            if (annotation != null) {
                String name = annotation.name();
                buffMap.put(name, e);
            }
        });

    }
}
